package org.backend.filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.backend.utils.JwtUtil;

import java.io.IOException;
import java.util.Set;

@WebFilter(urlPatterns = "/*")
@Slf4j
public class AuthorizationFilter implements Filter {

    private Set<String> excludePaths;

    // 初始化方法，web服务器启动的时候执行，只执行一次
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("初始化用户身份验证过滤器...");
        // 白名单必须写全接口路径
        excludePaths = Set.of(
                "/user/login",
                "/user/register",
                "/swagger-ui/index.html",
                "/swagger-ui/*",
                "/api-docs",
                "/api-docs/*",
                "/user/wxlogin"
        );
    }

    // 拦截到请求之后执行，执行多次
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 1、获取到请求路径
        String requestURI = request.getRequestURI();

        // 2、判断是否为需要放行的请求
        if (isPathInExcludeList(requestURI)) {
            log.info("白名单，放行");
            filterChain.doFilter(request, response);
            return;
        }

        // 3、获取请求头中的token
        String token = request.getHeader("Authorization"); // token放在哪个请求标头中，就写哪个

        // 4、判断token是否存在，如果不存在，返回错误信息
        if (token == null || token.isEmpty()) {
            log.info("令牌为空");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401状态码
            return;
        }

        if (!JwtUtil.validateToken(token)) {
            log.info("令牌过期");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401状态码
            response.getWriter().write("令牌无效或者过期");
            return;
        }

        // 5、如果token存在，校验令牌 -> 如果过期返回错误信息
        JwtUtil.parseToken(token);

        // 6、校验通过、放行
        log.info("令牌合法，通过");
        filterChain.doFilter(request, response);
    }

    // 对通配符进行配置
    private boolean isPathInExcludeList(String requestPath) {
        for (String excludePath : excludePaths) {
            if (excludePath.endsWith("*")) {
                // 处理带通配符的路径
                String basePath = excludePath.substring(0, excludePath.length() - 1);
                if (requestPath.startsWith(basePath)) {
                    return true;
                }
            } else if (requestPath.equals(excludePath)) {
                // 处理普通路径
                return true;
            }
        }
        return false;
    }

    // 销毁方法，web服务器关闭的时候执行，只执行一次
    @Override
    public void destroy() {
        log.info("用户身份验证过滤器销毁中...");
    }
}
